/*
* Copyright 2017 Baiyyy
* @(#)ApiPsZcdController.java
*/

package com.byyy.ccts.modules.api.controller;

import com.alibaba.fastjson.JSON;
import com.byyy.ccts.core.common.controller.BaseApiController;
import com.byyy.ccts.core.model.AjaxJson;
import com.byyy.ccts.core.query.wrapper.EntityWrapper;
import com.byyy.ccts.core.utils.StringUtils;
import com.byyy.ccts.modules.api.entity.DeliveryVo;
import com.byyy.ccts.modules.cc.entity.ccts.*;
import com.byyy.ccts.modules.cc.entity.vo.CkdInfo;
import com.byyy.ccts.modules.cc.enums.PsStateEnum;
import com.byyy.ccts.modules.cc.enums.WhetherOrNotEnum;
import com.byyy.ccts.modules.cc.enums.WorkingStateEnum;
import com.byyy.ccts.modules.cc.service.*;
import com.byyy.ccts.modules.common.annotation.LogRecord;
import com.byyy.ccts.modules.sys.entity.Cangku;
import com.byyy.ccts.modules.sys.service.IParamService;
import com.byyy.ccts.modules.sys.utils.UserUtils;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.validation.BindException;
import org.springframework.validation.BindingResult;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.util.Arrays;
import java.util.List;
import java.util.Map;

/**
* Created by DELL on 2019-8-13.
*/
@Controller
@Validated
@RequestMapping("/api/zcd")
public class ApiPsZcdController extends BaseApiController {

    @Autowired
    private IPsZcdService psZcdService;

    @Autowired
    private IPsZcdMxService psZcdMxService;

    @Autowired
    private IDeviceService deviceService;

    @Autowired
    private ICouvenseService couvenseService;

    @Autowired
    private IHumitureService humitureService;

    @Autowired
    private IParamService paramService;

    /**
     * API-装箱关联
     *
     */
    @RequestMapping(value = "relation", method = {RequestMethod.POST })
    @ResponseBody
    @LogRecord(title = "微信小程序-装箱关联")
    public AjaxJson relation(String relations, boolean isWhole) {
        AjaxJson info = new AjaxJson();
        info.setMsg("关联成功");
        ObjectMapper objectMapper = new ObjectMapper();
        List<TsRelation> relationList = null;
        String msg = null;
        relationList = JSON.parseArray(relations, TsRelation.class);
        msg = this.psZcdMxService.relationForApi(relationList, isWhole);
        if(StringUtils.isNotEmpty(msg)) {
            info.fail(msg);
        }

        return info;
    }

    /**
     * API-设备当前温度查询
     * @return
     */
    @ResponseBody
    @RequestMapping(value = "deviceCurTemp", method = { RequestMethod.GET, RequestMethod.POST })
    public AjaxJson deviceCurTemp(String zcdNo) {
        AjaxJson info = new AjaxJson();
        Map<String, Object> ret = null;
        ret = this.psZcdMxService.deviceCurTempForApi(zcdNo);

        if (StringUtils.isNotEmpty((String) ret.get("msg"))) {
            info.fail((String) ret.get("msg"));
            return info;
        }
        info.setData(ret.get("data"));
        return info;
    }

    /**
     * API-发车确认
     * @return
     */
    @ResponseBody
    @RequestMapping(value = "facConfirm", method = { RequestMethod.POST })
    @LogRecord(title = "微信小程序-装车确认")
    public AjaxJson facConfirm(String zcdNo) {
        AjaxJson info = new AjaxJson();
        info.setMsg("装车单[" + zcdNo + "]已发车");
        String msg = this.psZcdService.facConfirmForApi(zcdNo);
        if (StringUtils.isNotEmpty(msg)) {
            info.fail(msg);
        }
        return info;
    }

    /**
     * API-配送交接
     * @return
     */
    @ResponseBody
    @RequestMapping(value = "handOver", method = { RequestMethod.POST })
    @LogRecord(title = "微信小程序-配送交接")
    public AjaxJson handOver(String zcdNo, String address, boolean isWholePsjj) {
        if (StringUtils.isNotEmpty(address)) {
            try {
                address = URLDecoder.decode(address, "UTF-8");
            } catch (UnsupportedEncodingException e) {
                logger.error(e.getMessage(), e);
            }
        }
        AjaxJson info = new AjaxJson();
        String msg = this.psZcdService.handOverForApi(zcdNo, address, isWholePsjj);
        if (StringUtils.isNotEmpty(msg)) {
            info.fail(msg);
            return info;
        }

        StringBuilder sb = new StringBuilder();
        // 返回消息
        if (isWholePsjj) {
            sb.append("装车单整单交接完成[").append(zcdNo).append("]");
        }
        else {
            sb.append("装车单交接完成[").append(zcdNo).append(";").append(address).append("]");
        }
        info.setMsg(sb.toString());

        return info;
    }

    /**
     * API-装车单查询
     * @return
     */
    @ResponseBody
    @RequestMapping(value = "zcd", method = { RequestMethod.GET, RequestMethod.POST })
    public AjaxJson zcd(String zcdNo) {
        AjaxJson info = new AjaxJson();
        PsZcdHz zcd = this.psZcdService.selectById(zcdNo);
        if (zcd == null) {
            info.fail("未查询到装车单数据");
        }
        info.setData(zcd);
        return info;
    }

    /**
     * API-装车单列表查询
     * @return
     */
    @ResponseBody
    @RequestMapping(value = "zcdList", method = { RequestMethod.GET, RequestMethod.POST })
    public AjaxJson zcdList() {
        AjaxJson info = new AjaxJson();
        EntityWrapper<PsZcdHz> wrapper = new EntityWrapper<>();
        wrapper.ne("HZ_STATE", PsStateEnum.配送完成.getValue());
        List<PsZcdHz> zcdList = this.psZcdService.selectList(wrapper);
        if (zcdList == null || zcdList.size() < 1) {
            info.fail("未查询到装车单任务");
            return info;
        }
        info.setData(zcdList);
        return info;
    }

    /**
     * API-装车单明细查询
     * @return
     */
    @ResponseBody
    @RequestMapping(value = "zcdMx", method = { RequestMethod.GET, RequestMethod.POST })
    public AjaxJson zcdMx(String zcdNo) {
        AjaxJson info = new AjaxJson();
        List<PsZcdMx> zcdMxList = this.psZcdMxService.selectByZcdNos(Arrays.asList(zcdNo));
        if (zcdMxList == null || zcdMxList.size() < 1) {
            info.fail("未查询到装车单明细数据");
        }
        info.setData(zcdMxList);
        return info;
    }

    /**
     * API-采集设备详细信息查询
     * @return
     */
    @ResponseBody
    @RequestMapping(value = "deviceInfo", method = { RequestMethod.GET, RequestMethod.POST })
    public AjaxJson deviceInfo(String cjId) {
        AjaxJson info = new AjaxJson();
        List<Cangku> cangkuList = UserUtils.getUserCangkuList();
        if (cangkuList == null || cangkuList.size() < 1) {
            info.setRet(AjaxJson.RET_FAIL);
            return info;
        }
        String cangku = cangkuList.get(0).getCangku();
        List<TADevice> devices = this.deviceService.queryByNoAndCangku(Arrays.asList(cjId), cangku);
        if (devices == null || devices.size() < 1) {
            info.setRet(AjaxJson.RET_FAIL);
            return info;
        }

        devices = this.deviceService.queryTheLatestTemp(devices.get(0).getId());
        if (devices != null && devices.size() > 0) {
            info.setData(devices.get(0));
        }
        else {
            info.setRet(AjaxJson.RET_FAIL);
        }
        return info;
    }

    /**
     * API-采集设备查询
     * @return
     */
    @ResponseBody
    @RequestMapping(value = "device", method = { RequestMethod.GET, RequestMethod.POST })
    public AjaxJson device(String cjId) {
        AjaxJson info = new AjaxJson();
        List<Cangku> cangkuList = UserUtils.getUserCangkuList();
        if (cangkuList == null || cangkuList.size() < 1) {
            info.fail("该账户未配置仓库权限，无法查询设备信息，请确认");
            return info;
        }
        String cangku = cangkuList.get(0).getCangku();

        EntityWrapper<TADevice> wrapper = new EntityWrapper<>();
        wrapper.eq("no", cjId);
        wrapper.eq("state", WhetherOrNotEnum.是.getValue());
        wrapper.ne("working", WorkingStateEnum.已激活.getValue());
        wrapper.eq("cangku", cangku);
        TADevice device = this.deviceService.selectOne(wrapper);
        if (device == null) {
            info.fail("未查询到该设备信息，或者该设备未启用(或已激活)，请确认");
        }
        else {
            List<TSHumiture> humitureList = this.humitureService.queryLastedHumitureInfo(Arrays.asList(new String[] {device.getId()}));
            Float electricAlarm = paramService.getFloatValueByCode("ELECTRIC_ALARM");
            Float electricWarning = paramService.getFloatValueByCode("ELECTRIC_WARNING");
            if (humitureList == null || humitureList.size() < 1) {
                info.fail("未查询到设备最新的温度电量信息，请确认设备是否正常");
                return info;
            }
            device.setElectric(humitureList.get(0).getElectric());
            device.setElectricAlarm(electricAlarm.intValue());
            device.setElectricWarning(electricWarning.intValue());
            device.setCollectTime(humitureList.get(0).getCollectTime());
            info.setData(device);
        }
        return info;
    }

    /**
     * API-冷藏箱查询
     * @return
     */
    @ResponseBody
    @RequestMapping(value = "couvense", method = { RequestMethod.GET, RequestMethod.POST })
    public AjaxJson couvense(String lcSn) {
        AjaxJson info = new AjaxJson();
        List<Cangku> cangkuList = UserUtils.getUserCangkuList();
        if (cangkuList == null || cangkuList.size() < 1) {
            info.fail("该账户未配置仓库权限，无法查询设备信息，请确认");
            return info;
        }
        String cangku = cangkuList.get(0).getCangku();
        EntityWrapper<TACouvense> wrapper = new EntityWrapper<>();
        wrapper.eq("no", lcSn);
        wrapper.eq("state", WhetherOrNotEnum.是.getValue());
        wrapper.ne("working", WorkingStateEnum.已激活.getValue());
        wrapper.eq("cangku", cangku);
        TACouvense couvense = this.couvenseService.selectOne(wrapper);
        if (couvense == null) {
            info.fail("未查询到该保温箱信息，或者该保温箱未启用(或已激活)，请确认");
        }
        return info;
    }

    /**
     * API-流水号查询
     * @return
     */
    @ResponseBody
    @RequestMapping(value = "liushBarcode", method = { RequestMethod.GET, RequestMethod.POST })
    public AjaxJson liushBarcode(String liushBarcode) {
        AjaxJson info = new AjaxJson();
        EntityWrapper<PsZcdMx> wrapper = new EntityWrapper<>();
        List<PsZcdMx> psZcdMxList = this.psZcdMxService.selectByBarcodes(Arrays.asList(liushBarcode));
        if (psZcdMxList == null || psZcdMxList.size() < 1) {
            wrapper = new EntityWrapper<>();
            wrapper.eq("MX_ZHUANGCD_NO", liushBarcode);
            psZcdMxList = this.psZcdMxService.selectList(wrapper);
            if (psZcdMxList == null || psZcdMxList.size() < 1) {
                info.fail("未能根据流水号或装车单查询到相应的装车单信息，或者装车单尚未下传，请确认");
                return info;
            }

        }
        info.setData(psZcdMxList.stream().mapToInt(PsZcdMx::getShijJs).sum());
        return info;
    }

    /**
     * API-根据流水号拆分装车单
     * @return
     */
    @ResponseBody
    @RequestMapping(value = "zcdSplit", method = { RequestMethod.POST })
    @LogRecord(title = "微信小程序-装车单拆分")
    public AjaxJson zcdSplit(String cjId, String lcSn, String liushBarcode, int splitNumber) {
        AjaxJson info = new AjaxJson();
        String ret = this.psZcdMxService.zcdSplitForApi(cjId, lcSn, liushBarcode, splitNumber);
        if (StringUtils.isNotEmpty(ret)) {
            info.fail(ret);
        }
        return info;
    }

    /**
     * API-根据流水号或者业务单号查询出库单信息以及流程状态
     * @return
     */
    @ResponseBody
    @RequestMapping(value = "getCkdInfo", method = { RequestMethod.POST })
    public AjaxJson getCkdInfo(String liushBarcode) {
        AjaxJson ajaxJson = new AjaxJson();
        CkdInfo info = this.psZcdService.queryCkdInfo(liushBarcode);
        ajaxJson.setData(info);
        return ajaxJson;
    }

    /**
     * 配送装车单下发接口
     * @param deliveryVo
     * @return
     */
    @RequestMapping(value = "/delivery", method = RequestMethod.POST)
    @ResponseBody
    public AjaxJson delivery(@RequestBody @Valid DeliveryVo deliveryVo) {
        AjaxJson ajaxJson = new AjaxJson();
        this.psZcdService.delivery(deliveryVo);
        return ajaxJson;
    }

    @RequestMapping(value = "back", method = {RequestMethod.POST})
    @ResponseBody
    public AjaxJson back(HttpServletRequest request, HttpServletResponse response) {
        AjaxJson ajaxJson = new AjaxJson();
        String zcdNos = request.getParameter("zcdNos");
        ajaxJson.success("装车启运信息反馈完毕");
        String msg = this.psZcdService.back(Arrays.asList(zcdNos.split(",")));
        if (!StringUtils.isEmpty(msg)) {
            ajaxJson.fail(msg);
        }
        return ajaxJson;
    }

    @Override
    @ExceptionHandler(value = {Exception.class})
    @ResponseBody
    public AjaxJson validationExceptionHandler(Exception e) {
        AjaxJson json = new AjaxJson();
        BindingResult result = null;
        if (e instanceof BindException) {
            result = ((BindException) e).getBindingResult();
        }
        else if (e instanceof MethodArgumentNotValidException) {
            result = ((MethodArgumentNotValidException) e).getBindingResult();
        }
        else {
            json.fail(e.getMessage());
            return json;
        }
        String msg = null;
        if (result != null && result.hasErrors()) {
            msg = result.getAllErrors().get(0).getDefaultMessage();
            if (msg.contains("NumberFormatException")) {
                msg = "参数类型错误！";
            }
        }
        else {
            msg = "系统繁忙，请稍后再试...";
        }
        json.fail(msg);
        return json;
    }

}
